package com.snake.controllers;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.apache.log4j.Logger;
import org.dom4j.DocumentException;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.snake.models.WxComponentToken;
import com.snake.repositories.WxComponentTokenService;
import com.snake.util.ComponentWxUtil;
import com.snake.util.aes.AesException;

/**
 * 
 */
@RestController
@RequestMapping(value = "/api/method/componentWX")
public class ComponentWXController extends BaseController{
	public static Logger logger = Logger.getLogger(ComponentWXController.class
			.getName());
	@Value("${wx.componentAppid}")
	private String componentAppid;
	@Value("${wx.componentAppSecret}")
	private String componentAppSecret;
	@Value("${wx.component_token}")
	private String componentToken;
	@Value("${wx.component_encodingaeskey}")
	private String componentEncodingaeskey;
	@Value("${wx.id}")
	private String id;
	@Autowired
	private WxComponentTokenService wxComponentTokenService;
	
	/*
	 * 获取推送的component_verify_ticket保存到数据库
	 */
	@RequestMapping(value = "/getComponentVerifyTicket", method = RequestMethod.GET)
	public void getComponentVerifyTicket(HttpServletRequest request,HttpServletResponse response) {
		try {
			String processAuthorizeEvent =ComponentWxUtil.processAuthorizeEvent(request,componentToken,componentEncodingaeskey,componentAppid,id);
			if(processAuthorizeEvent!=null && !processAuthorizeEvent.equals("")){
				Map<String, Object> params=new HashMap<String, Object>();
				params.put("type", "componentVerifyTicket");
				params.put("componentAppid",componentAppid);
				List<WxComponentToken> byList = wxComponentTokenService.getByList(params);
				if(byList.size()>0){
					byList.get(0).setComponentValue(processAuthorizeEvent);
					wxComponentTokenService.update(byList.get(0));
				}else{
					WxComponentToken wxComponentToken=new WxComponentToken();
					wxComponentToken.setComponentAppid(componentAppid);
					wxComponentToken.setComponentValue(processAuthorizeEvent);
					wxComponentToken.setType("componentVerifyTicket");
				}
			}else{
				logger.error("获取component_verify_ticket失败");
			}
			ComponentWxUtil.output(response, "success"); // 输出响应的内容。
		} catch (DocumentException | AesException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			logger.error("获取component_verify_ticket出错:"+e.toString());
			ComponentWxUtil.output(response, "success"); // 输出响应的内容。
		}
	}
	
	@RequestMapping(value = "/redirectUrl", method = RequestMethod.GET)
	public void redirectUrl(@RequestParam("auth_code") String authCode,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		try{
			String authorizerAccessToken = getAuthorizerInfo(authCode);
			System.out.println("authorizerAccessToken:"+authorizerAccessToken);
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("---------------使用授权码换取公众号的接口调用凭据和授权信息失败:"+e.toString());
			logger.error("--------------------------使用授权码换取公众号的接口调用凭据和授权信息-------------e:"
					+ e.toString());
		}
	}
	
	@RequestMapping(value = "/getPreAuthCode", method = RequestMethod.GET)
	public Map<String, Object> getPreAuthCode(
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		try{
			String preAuthCode = getPreAuthCode();
			if (preAuthCode == null||preAuthCode.equals("")) {
				return getReturnMapFailure("获取PreAuthCode失败");
			}
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("preAuthCode", preAuthCode);
			return getReturnMapSuccess(map);
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("---------------getPreAuthCode接口失败:"+e.toString());
			logger.error("--------------------------getPreAuthCode接口error-------------e:"
					+ e.toString());
			return getReturnMapFailure("获取PreAuthCode失败");
		}
	}
	/*
	 * 使用授权码换取公众号的接口调用凭据和授权信息
	 */
	public String getAuthorizerInfo(String authCode) {
		String authorizerAccessToken="";
		if(authCode==null||authCode.equals("")){
			return "";
		}
		System.out.println("-----getAuthorizerInfo-----------authCode:"+authCode);
		logger.error("----------------getAuthorizerInfo------------authCode:"+ authCode);
		String componentAccessToken = getComponentAccessToken();
		try {
			Map<String, Object> authorizationInfoMap = ComponentWxUtil.getAuthorizationInfo(componentAppid,componentAccessToken,authCode);
			WxComponentToken wxComponentToken=new WxComponentToken();
			wxComponentToken.setComponentAppid(componentAppid);
			wxComponentToken.setComponentValue(authorizationInfoMap.get("authorizerAccessToken").toString());
			wxComponentToken.setExpiresIn(authorizationInfoMap.get("accessExpires").toString());
			wxComponentToken.setType("authorizerAccessToken");
			wxComponentTokenService.add(wxComponentToken);
			WxComponentToken wxComponentToken2=new WxComponentToken();
			wxComponentToken2.setComponentAppid(componentAppid);
			wxComponentToken2.setComponentValue(authorizationInfoMap.get("authorizerRefreshToken").toString());
			wxComponentToken2.setType("authorizerRefreshToken");
			wxComponentTokenService.add(wxComponentToken2);
			authorizerAccessToken=authorizationInfoMap.get("authorizerAccessToken").toString();
		} catch (JsonProcessingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			logger.error("获取AuthorizerInfo出错:"+e.toString());
		}
		return authorizerAccessToken;
	}
	
	/*
	 * 获取预授权码pre_auth_code
	 */
	public String getPreAuthCode() {
		String preAuthCode="";
		try {
			//1.先查询数据库里是否有preAuthCode数据
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("type", "preAuthCode");
			params.put("componentAppid", componentAppid);
			List<WxComponentToken> preAuthCodeList = wxComponentTokenService.getByList(params);
			if(preAuthCodeList.size()>0){
				//判断preAuthCode是否过期
				boolean tokenIsValidity = ComponentWxUtil.tokenIsValidity(preAuthCodeList.get(0));
				if(tokenIsValidity){
					preAuthCode=preAuthCodeList.get(0).getComponentValue();
				}else{
					String componentAccessToken = getComponentAccessToken();
					if(componentAccessToken!=null&&!componentAccessToken.equals("")){
						Map<String, Object> preAuthCodeMap = ComponentWxUtil.getPreAuthCode(componentAppid,componentAccessToken);
						if(preAuthCodeMap!=null){
							preAuthCodeList.get(0).setComponentAppid(componentAppid);
							preAuthCodeList.get(0).setComponentValue(preAuthCodeMap.get("preAuthCode").toString());
							preAuthCodeList.get(0).setExpiresIn(preAuthCodeMap.get("accessExpires").toString());
							preAuthCodeList.get(0).setType("preAuthCode");
							wxComponentTokenService.update(preAuthCodeList.get(0));
							preAuthCode=preAuthCodeMap.get("preAuthCode").toString();
						}
					}
				}
			}else{
				String componentAccessToken = getComponentAccessToken();
				if(componentAccessToken!=null&&!componentAccessToken.equals("")){
					Map<String, Object> preAuthCodeMap = ComponentWxUtil.getPreAuthCode(componentAppid,componentAccessToken);
					if(preAuthCodeMap!=null){
						WxComponentToken wxComponentToken=new WxComponentToken();
						wxComponentToken.setComponentAppid(componentAppid);
						wxComponentToken.setComponentValue(preAuthCodeMap.get("preAuthCode").toString());
						wxComponentToken.setExpiresIn(preAuthCodeMap.get("accessExpires").toString());
						wxComponentToken.setType("preAuthCode");
						wxComponentTokenService.add(wxComponentToken);
						preAuthCode=preAuthCodeMap.get("preAuthCode").toString();
					}
				}
			}
		}catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			logger.error("获取pre_auth_code出错:"+e.toString());
		}
		return preAuthCode;
	}
	
	
	/*
	 * 获取第三方的component_access_token
	 */
	public String getComponentAccessToken() {
		String componentAccessToken="";
		try {
			Map<String, Object> params = new HashMap<String, Object>();
			//1.先查询数据库里是否有ComponentAccessToken数据
			params.put("type", "componentAccessToken");
			params.put("componentAppid", componentAppid);
			List<WxComponentToken> componentAccessTokenList = wxComponentTokenService.getByList(params);
			if(componentAccessTokenList.size()>0){
				//判断componentAccessToken是否过期
				boolean tokenIsValidity = ComponentWxUtil.tokenIsValidity(componentAccessTokenList.get(0));
				if(tokenIsValidity){
					componentAccessToken=componentAccessTokenList.get(0).getComponentValue();
				}else{
					params.clear();
					params.put("type", "componentVerifyTicket");
					params.put("componentAppid", componentAppid);
					List<WxComponentToken> componentVerifyTicketList = wxComponentTokenService.getByList(params);
					if(componentVerifyTicketList.size()>0){
						Map<String, Object> componentAccessTokenMap = ComponentWxUtil.getComponentAccessToken(componentAppid,componentAppSecret,componentVerifyTicketList.get(0).getComponentValue());
						if(componentAccessTokenMap!=null){
							componentAccessTokenList.get(0).setComponentAppid(componentAppid);
							componentAccessTokenList.get(0).setComponentValue(componentAccessTokenMap.get("componentAccessToken").toString());
							componentAccessTokenList.get(0).setExpiresIn(componentAccessTokenMap.get("accessExpires").toString());
							componentAccessTokenList.get(0).setType("componentAccessToken");
							wxComponentTokenService.update(componentAccessTokenList.get(0));
							componentAccessToken=componentAccessTokenMap.get("componentAccessToken").toString();

						}
					}
				}
			}else{
				params.clear();
				params.put("type", "componentVerifyTicket");
				params.put("componentAppid", componentAppid);
				List<WxComponentToken> componentVerifyTicketList = wxComponentTokenService.getByList(params);
				if(componentVerifyTicketList.size()>0){
					Map<String, Object> componentAccessTokenMap = ComponentWxUtil.getComponentAccessToken(componentAppid,componentAppSecret,componentVerifyTicketList.get(0).getComponentValue());
					if(componentAccessTokenMap!=null){
						WxComponentToken wxComponentToken=new WxComponentToken();
						wxComponentToken.setComponentAppid(componentAppid);
						wxComponentToken.setComponentValue(componentAccessTokenMap.get("componentAccessToken").toString());
						wxComponentToken.setExpiresIn(componentAccessTokenMap.get("accessExpires").toString());
						wxComponentToken.setType("componentAccessToken");
						wxComponentTokenService.add(wxComponentToken);
						componentAccessToken=componentAccessTokenMap.get("componentAccessToken").toString();
					}
				}
			}
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			logger.error("获取component_access_token出错:"+e.toString());
		}
		return componentAccessToken;
	}
}